package com.yuncheng.sms.controller;

import com.yuncheng.common.utils.IPUtils;
import com.yuncheng.sms.service.ApiSignManager;
import com.yuncheng.sms.service.LoginSysConfigService;
import com.yuncheng.sms.utils.LoginSysConfig;
import com.yuncheng.system.sysconfig.service.ISysConfigService;
import com.yuncheng.util.SignUtil;
import com.yuncheng.vo.HttpResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * 短信验证码管理
 *
 * @date 2023/4/10
 */
@Controller
public class SmsManagerController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private LoginSysConfigService loginSysConfigService;

    @Autowired
    private ISysConfigService sysConfigService;

    @Autowired
    private ApiSignManager apiSignManager;

    /** 登录弱密码-修改密码 */
    @RequestMapping(value = "/api/system/user/changeWeakPassword", method = {RequestMethod.POST, RequestMethod.PUT})
    @ResponseBody
    public HttpResult<?> changeWeakPassword(HttpServletRequest request) {
        String username = (null != request.getUserPrincipal()) ? request.getUserPrincipal().getName() : null;
        String oldpassword = request.getParameter("oldpassword");
        String password = request.getParameter("password");
        String confirmpassword = request.getParameter("confirmpassword");

        if (StringUtils.hasText(username)
                && StringUtils.hasText(oldpassword)
                && StringUtils.hasText(password)
                && StringUtils.hasText(confirmpassword)) {
            return loginSysConfigService.changeWeakPassword(username, oldpassword, password, confirmpassword);
        }

        return HttpResult.error(401, "无效的请求数据！");
    }

    /** 刷新系统配置、内网ip验证 */
    @RequestMapping(value = "/api/login/refreshconfig")
    @ResponseBody
    public HttpResult<?> refreshConfig(HttpServletRequest request) {
        loginSysConfigService.refreshConfig();
        logger.info("#####refreshConfig#####");
        apiSignManager.refreshNeedSmscodeServerIpsFromSysConfig();
        return HttpResult.ok();
    }

    /** 弱密码验证-开启状态 */
    @RequestMapping(value = "/api/login/weakstatus")
    @ResponseBody
    public HttpResult<?> weakStatus(HttpServletRequest request) {
        Object result = sysConfigService.querySysConfigByCode(LoginSysConfig.LOGIN_CHANGE_WEAK_PASSWORD.getConfigCode());
        logger.debug("#####weakStatus##### result=" + result);
        return HttpResult.ok(result);
    }

    /** 内网是否校验-验证码-开启状态 */
    @RequestMapping(value = "/api/login/status")
    @ResponseBody
    public HttpResult<?> loginStatus(HttpServletRequest request) {
        int smscode = loginSysConfigService.checkPcNeedSmsCode(IPUtils.getIpAddr(request));
        if (apiSignManager.isNeedSmscodeServer(IPUtils.getIpAddr(request))) {
            // 是需要发送验证码的内网服务器IP，则根据islan参数决定是否校验验证码
            if (LoginSysConfigService.LOGIN_ISLAN_NOVERIFY.equals(request.getParameter(LoginSysConfigService.LOGIN_ISLAN_KEY))) {
                //接收到内网无校验标志，不需要校验验证码
                smscode = LoginSysConfigService.NO_SMSCODE;
            } else {
                // 其他情况都需要校验验证码
                smscode = LoginSysConfigService.NEED_SMSCODE;
            }
        }
        Map<String, Object> result = new HashMap<>();
        result.put("smscode", smscode);
        logger.debug("#####loginStatus##### result=" + result);
        return HttpResult.ok(result);
    }

    /** 获取登录短信验证码 */
    @RequestMapping(value = "/api/login/smscode")
    @ResponseBody
    public HttpResult<?> smsCode(HttpServletRequest request, HttpServletResponse response) {
        String ipAddr = IPUtils.getIpAddr(request);
        int smscode = loginSysConfigService.checkPcNeedSmsCode(ipAddr);
        if (LoginSysConfigService.NO_SMSCODE == smscode) {
            if (apiSignManager.isNeedSmscodeServer(ipAddr)) {
                // 是需要发送验证码的内网服务器IP，设置发送验证码标志
                smscode = LoginSysConfigService.NEED_SMSCODE;
            }
        }
        boolean hasSign = false;
        if (StringUtils.hasText(request.getParameter(SignUtil.SIGN_KEY))) {
            // 带有参数签名，校验参数签名和相关验证
            HttpResult<?> checkResult = apiSignManager.checkApiSign(request, "username", "password");
            if (checkResult.isSuccess()) {
                // 参数校验成功，设置需要发送短信验证码
                smscode = LoginSysConfigService.NEED_SMSCODE;
                hasSign = true;
            } else {
                // 参数校验失败，返回失败原因信息
                return checkResult;
            }
        }
        Map<String, Object> result = null;
        if (LoginSysConfigService.NEED_SMSCODE == smscode) {
            try {
                if (loginSysConfigService.checkUserData(request, response)) {
                    String username = loginSysConfigService.obtainUserName(request);
                    result = loginSysConfigService.sendSmsVerifyCode(username);
                    if (null == result) {
                        return HttpResult.error(401, LoginSysConfigService.SMS_SEND_ERROR_MSG);
                    } else if (!result.containsKey(LoginSysConfigService.SMS_SEND_ID_KEY)) {
                        Object msg = result.get(LoginSysConfigService.SMS_SEND_MSG_KEY);
                        if(msg!=null){
                            return HttpResult.error(401, msg.toString());
                        }
                        return HttpResult.error(401, LoginSysConfigService.SMS_SEND_ERROR_MSG);
                    } else if (hasSign) {
                        // 是服务器端带参数签名请求发送的，则设置signcode标记
                        loginSysConfigService.saveSignCode(username, String.valueOf(result.get(LoginSysConfigService.SMS_SEND_ID_KEY)));
                    }
                } else {
                    return HttpResult.error(401, "用户名或密码错误。");
                }
            } catch (RuntimeException e) {
                return HttpResult.error(401, e.getMessage());
            }
        } else {
            result = new HashMap<>();
            result.put("nosmscode", 1);
            result.put(LoginSysConfigService.SMS_SEND_MSG_KEY, "当前登录不需要验证码。");
        }
        return HttpResult.ok(result);
    }

}
